import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'

export default function useMoveScreen() {
  /** 是否是放大浏览状态*/
  const isScreen = useRef(false)
  /** 放大浏览元素*/
  const [domStyle, setDomStyle] = useState<React.CSSProperties>({});
  const initDomInfo = useRef({
    height: 0,
    width: 0
  })
  const frameDom = useRef<any>(null)
  const coveringAgentDom = useRef<null | Element>(null)
  const copyStyle = useRef<any>("")

  /** 放大浏览之前元素的页面中的left和top*/
  const lastOffset = useRef({
    top: 0,
    left: 0
  })


  /** 初始化dom信息*/
  const onInitDom = useCallback(() => {
    let boundingClientRect = frameDom.current.getBoundingClientRect();
    initDomInfo.current.height = boundingClientRect.height
    initDomInfo.current.width = boundingClientRect.width

  }, [])

  /** 点击Dom放大浏览 */
  const moveToScreen = useCallback(() => {
    if (coveringAgentDom.current === null) {
      return
    }
    let enlargedScale = getEnlargedScale();
    let { transformX, transformY } = getDisplaceDistance()
    if (isScreen.current === false) {
      (coveringAgentDom.current as HTMLDivElement).style.display = 'block';

      const { x, y } = frameDom.current.getBoundingClientRect();
      lastOffset.current.left = x;
      lastOffset.current.top = y;
      document.documentElement.style.overflow = "hidden";

      //添加占位元素
      let newElement = document.createElement("div");
      newElement.style.cssText = copyStyle.current;
      frameDom.current.parentNode.insertBefore(newElement, frameDom.current);
      
      setDomStyle({
        position: 'fixed',
        top: `${y}px`,
        left: `${x}px`,
        margin: 0,
        transform: `translate(${transformX}px,${transformY}px) scale(${enlargedScale},${enlargedScale})`,
        zIndex: 99,
      });
      isScreen.current = true
    } else {
      document.documentElement.style.overflow = "";
      (coveringAgentDom.current as HTMLDivElement).style.display = 'none';
      setDomStyle({
        transform: `translate(0px,0px) scale(1,1)`,
      });
      //移除占位元素
      frameDom.current.parentNode.removeChild(frameDom.current.previousSibling);
      isScreen.current = false
    }
  }, [])

  /** 计算放大比例*/
  const getEnlargedScale = useCallback(() => {
    const { height, width } = initDomInfo.current
    const screenWidth = window.innerWidth;
    const screenHeight = window.innerHeight;
    let heightRatio = screenHeight / height;
    let widthRatio = screenWidth / width;

    return heightRatio > widthRatio ? widthRatio * 0.8 : heightRatio * 0.8;
  }, [])

  /** 获取移动距离 */
  const getDisplaceDistance = useCallback((isSizeChange: boolean = false) => {
    if (frameDom.current === null) {
      return {
        transformX: 0,
        transformY: 0
      }
    }

    const { left, top } = frameDom.current.getBoundingClientRect();
    const { width, height } = initDomInfo.current;
    const screenWidth = window.innerWidth;
    const screenHeight = window.innerHeight;

    let transformX = screenWidth / 2 - (left + width / 2)
    let transformY = screenHeight / 2 - (top + height / 2)


    //left和top要使用进入浏览状态时的left和top
    if (isSizeChange === true) {
      transformX = screenWidth / 2 - (lastOffset.current.left + width / 2)
      transformY = screenHeight / 2 - (lastOffset.current.top + height / 2)
    }

    return {
      transformX,
      transformY
    }
  }, [])

  /** 创建遮盖层*/
  const createCoveringAgent = useCallback(() => {
    const element = document.createElement('div')
    element.className = 'coveringAgent'
    element.style.position = 'fixed'
    element.style.zIndex = '98'
    element.style.top = '0'
    element.style.left = '0'
    element.style.height = '100vh'
    element.style.width = '100vw'
    element.style.backdropFilter = 'blur(10px)'
    element.style.color = '#fff'
    element.style.boxShadow = '0 0 30px 10px rgba(0, 0, 0, .3)'
    element.style.display = 'none'

    return element
  }, [])


  /** 浏览器尺寸发生变化*/
  const changeSize = useCallback(() => {
    if (!isScreen.current) {
      return
    }
    let { transformX, transformY } = getDisplaceDistance(true)
    let enlargedScale = getEnlargedScale();
    setDomStyle({
      position: 'fixed',
      top: `${lastOffset.current.top}px`,
      left: `${lastOffset.current.left}px`,
      margin: 0,
      zIndex: 99,
      transform: `translate(${transformX}px,${transformY}px) scale(${enlargedScale},${enlargedScale})`,
    });
  }, [])

  /** 复制元素样式*/
  const copyStyleFn = useCallback(() => {
    const styles = window.getComputedStyle(frameDom.current);
    let cssText = styles.cssText;
    if (!cssText) {
      cssText = Array.from(styles).reduce((str, property) => {
        return `${str}${property}:${styles.getPropertyValue(property)};`;
      }, '');
    }
    cssText += 'opacity:0; '
    copyStyle.current = cssText;
  }, [])

  const onWheel = useCallback((e: any) => {
    e.preventDefault()
  }, [])

  useEffect(() => {
    if (frameDom.current === null) {
      return
    }
    onInitDom()
    copyStyleFn()

    //判断是否创建遮盖层
    let coveringAgentElement = window.document.querySelector('.coveringAgent')
    if (coveringAgentElement) {
      coveringAgentDom.current = coveringAgentElement as HTMLDivElement;
    } else {
      let element = createCoveringAgent()
      coveringAgentDom.current = element;
      window.document.body.appendChild(element)
    }

    frameDom.current.style.transition = "all .2s linear";
    frameDom.current.addEventListener("click", moveToScreen);
    window.addEventListener('resize', changeSize);
    return () => {
      window.removeEventListener('resize', changeSize);
      frameDom.current && frameDom.current.removeEventListener("click", moveToScreen);
    }
  }, [])


  useEffect(() => {
    if (isScreen.current) {
      frameDom.current.addEventListener('wheel', onWheel)
    } else {
      frameDom.current && frameDom.current.removeEventListener('wheel', onWheel)
    }
  }, [isScreen.current])

  return {
    frameDom,
    domStyle,
  }
}